package cn.edu.zut.soft.graduate.reportCenter.service.Impl;

import cn.edu.zut.soft.basic.core.model.dao.Query;
import cn.edu.zut.soft.graduate.base.cache.CachePool;
import cn.edu.zut.soft.graduate.base.former.InfoIdentityTransformer;
import cn.edu.zut.soft.graduate.core.constant.InfoType;
import cn.edu.zut.soft.graduate.core.design.BasicInfoStrategy;
import cn.edu.zut.soft.graduate.core.design.InfoStrategy;
import cn.edu.zut.soft.graduate.core.model.Impl.Info;
import cn.edu.zut.soft.graduate.core.model.Impl.ReportCount;
import cn.edu.zut.soft.graduate.core.vo.LoginVO;
import cn.edu.zut.soft.graduate.reportCenter.pojo.*;
import cn.edu.zut.soft.graduate.reportCenter.query.Impl.SimpleReportDataQuery;
import cn.edu.zut.soft.graduate.reportCenter.query.SearchReportQuery;
import cn.edu.zut.soft.graduate.reportCenter.service.ReportCenterService;
import cn.edu.zut.soft.graduate.reportCenter.service.ReportDataBO;
import cn.edu.zut.soft.graduate.reportCenter.service.ReportRuleBO;
import cn.edu.zut.soft.graduate.userCenter.bo.IdentityBO;
import cn.edu.zut.soft.graduate.userCenter.bo.InfoBO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 关于报告服务
 *
 * @author cc
 * @Date 2017/2/13
 * @value 1.0
 */
@Service
public class ReportCenterServiceImpl implements ReportCenterService {

    @Autowired
    private ReportRuleBO reportRuleBO;

    @Autowired
    private ReportDataBO reportDataBO;

    @Autowired
    private InfoBO infoBO;

    @Autowired
    private IdentityBO identityBO;

    @Autowired
    private InfoIdentityTransformer infoIdentityTransformer;

    @Override
    public boolean addReportRule(ReportRuleDTO reportRuleDTO, LoginVO loginVO) {
        if (reportRuleDTO instanceof ReportRule) {
            reportRuleBO.save((ReportRule) reportRuleDTO, loginVO.getName());
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean addReportRuleAll(Collection<ReportRuleDTO> reportRuleDTOs, LoginVO loginVO) {
        for (ReportRuleDTO reportRuleDTO : reportRuleDTOs) {
            reportRuleBO.save((ReportRule) reportRuleDTO, loginVO.getName());
        }
        return true;
    }

    @Override
    public ReportRule getRule(Integer ruleId) {
        if (ruleId == null) {
            throw new IllegalArgumentException("rule_id is null");
        }
        return reportRuleBO.get(ruleId);
    }

    @Override
    public List listRule(Query query) {
        List result = reportRuleBO.findByQuery(query).getData();
        return result;
    }

//    @Override
//    public boolean updateReportRule(ReportRuleDTO reportRuleDTO,LoginVO loginVO) {
////        CachePool.reportRuleCacheMap.remove(reportRuleDTO.getId());
////        reportRuleBO.update((ReportRule) reportRuleDTO,loginVO.getName());
//        return true;
//    }

    @Override
    public ReportRule removeReportRule(Integer ruleId, LoginVO loginVO) {
        SimpleReportDataQuery simpleReportDataQuery = new SimpleReportDataQuery();
        simpleReportDataQuery.setRuleIds(Collections.singletonList(ruleId));
        List<ReportData> reportDataDTOList = reportDataBO.findByQuery(simpleReportDataQuery).getData();
        if (!reportDataDTOList.isEmpty()) {
            throw new IllegalArgumentException("当前规则下存在已提交报告("+reportDataDTOList.size()+"个),不得删除,请清理数据");
        }
        CachePool.reportRuleCacheMap.remove(ruleId);
        return reportRuleBO.delete(ruleId, loginVO.getName()).getData();
    }

    @Override
    public boolean addReportData(ReportDataDTO reportDataDTO, LoginVO loginVO) {
        ReportRuleDTO ruleDTO = getRule(reportDataDTO.getReportRuleId());
        if (ruleDTO == null) {
            throw new IllegalArgumentException("rule is not have");
        }
        if (ruleDTO.getRepeat() == 1) {
            //根据 id 和 loginvo查找报告
            SimpleReportDataQuery simpleReportDataQuery = new SimpleReportDataQuery();
            simpleReportDataQuery.setIdentityIds(Collections.singletonList(loginVO.getId()));
            simpleReportDataQuery.setRuleIds(Collections.singletonList(reportDataDTO.getReportRuleId()));
            List<ReportData> reportDataDTOList = reportDataBO.findByQuery(simpleReportDataQuery).getData();
            if (!reportDataDTOList.isEmpty()) {
                throw new IllegalArgumentException("报告已经存在,请勿重复提交");
            }
        }
        ReportData reportData = (ReportData) reportDataDTO;
        Date nowDate = new Date();
        if (ruleDTO.getStartTime().compareTo(nowDate) > 0) {
            throw new IllegalArgumentException("时间还未开始");
        }
        reportData.setHashContext(reportData.getContext().hashCode());
        reportData.setIdentityRole(loginVO.getRole());
        reportData.setIdentityName(loginVO.getName());
        reportData.setIdentityId(loginVO.getId());
        if (ruleDTO.getEndTime().compareTo(nowDate) <= 0) {
            reportData.setSupplement(1);
        }
        reportDataBO.save(reportData, loginVO.getName());
        return true;
    }

    @Override
    public List<ReportRule> findRuleByDateOfLoginVO(Date date, LoginVO loginVO) {
        // TODO: 2017/2/13
        List<ReportRule> reportRuleList;
        SimpleReportDataQuery simpleReportDataQuery = new SimpleReportDataQuery();
        if (null == date){
            //补交逻辑
            simpleReportDataQuery.setPageSize(Integer.MAX_VALUE);
            reportRuleList = reportRuleBO.findByQuery(simpleReportDataQuery).getData();
        }else {
            //刷新逻辑 超时提示语提示 正式提交周月报时间已经结束
            reportRuleList = reportRuleBO.findRuleByDate(date);
        }
        Set<Integer> ids = new HashSet<>(reportRuleList.size());
        for (ReportRule reportRule : reportRuleList) {
            ids.add(reportRule.getId());
        }
        SimpleReportDataQuery reportDataQuery = new SimpleReportDataQuery();
        reportDataQuery.setRuleIds(new ArrayList<Integer>(ids));
        reportDataQuery.setIdentityIds(Collections.singletonList(loginVO.getId()));
        //根据ruleids和identityIds 查询数据
        List<ReportData> reportDataList = reportDataBO.findByQuery(reportDataQuery).getData();
        for (ReportData reportData : reportDataList) {
            ids.remove(reportData.getReportRuleId());
        }
        final Set<Integer> finalIds = ids;
        List<ReportRule> result = new ArrayList<>(finalIds.size());
        CollectionUtils.select(reportRuleList, new Predicate() {
            @Override
            public boolean evaluate(Object o) {
                return finalIds.contains(((ReportRule) o).getId());
            }
        }, result);
        return result;
    }

    @Override
    public boolean updateReportData(ReportDataDTO reportDataDTO, LoginVO loginVO) {
        if (reportDataDTO.getId() == null) {
            throw new IllegalArgumentException("id is null");
        }
        ReportData reportData = reportDataBO.get(reportDataDTO.getId());
        int hashCode = reportDataDTO.getContext().hashCode();
        if (reportData.getContext().hashCode() == hashCode) {
            throw new IllegalArgumentException("内容没有修改");
        }
        reportData.setContext(reportDataDTO.getContext());
        reportData.setHashContext(hashCode);
        reportDataBO.update(reportData, loginVO.getName()).getData();
        return true;
    }

    @Override
    public ReportDataDTO removeReportData(Integer dataId, LoginVO loginVO) {
        ReportData reportData = reportDataBO.get(dataId);
        if (reportData == null){
            return null;
        }
        reportData.setDel(-1);
        return reportDataBO.update(reportData, loginVO.getName()).getData();
    }

    @Override
    public ReportDataDTO getReportData(Integer dataId) {
        return reportDataBO.get(dataId);
    }


    @Override
    public List<ReportDataDTO> listReportData(Query query) {
        List<ReportData> dataList = reportDataBO.findByQuery(query).getData();
        List<ReportDataDTO> list = new ArrayList<>(dataList.size());
        list.addAll(dataList);
        return list;
    }

    @Override
    public List<ReportDataSearchVO> statisticsStudentOfQuery(SearchReportQuery rs) {
        SimpleReportDataQuery reportDataQuery = new SimpleReportDataQuery();
        reportDataQuery.setLimit(rs.getLimit());
        reportDataQuery.setOffset(rs.getOffset());

        if (rs.getTeaGroupId() != null || rs.getTeaId() != null) {
            List<InfoStrategy> infoStrategyList = new ArrayList<>();
            BasicInfoStrategy bs;
            if (rs.getTeaGroupId() != null) {
                bs = new BasicInfoStrategy();
                bs.setKey("group");
                bs.setType(InfoType.Group);
                bs.setValue(rs.getTeaGroupId().toString());
                List<Info> teaList = infoBO.queryByInfoStrategy(Collections.<InfoStrategy>singletonList(bs));
                if (teaList.isEmpty()) {
                    return Collections.emptyList();
                }
                for (Info info : teaList) {
                    bs = new BasicInfoStrategy();
                    bs.setKey("guide");
                    bs.setType(InfoType.Tea);
                    bs.setValue(info.getIdentityId().toString());
                    infoStrategyList.add(bs);
                }

            } else if (rs.getTeaId() != null) {
                bs = new BasicInfoStrategy();
                bs.setKey("guide");
                bs.setType(InfoType.Tea);
                bs.setValue(rs.getTeaId().toString());
                infoStrategyList.add(bs);
            }
            List<Info> infoList = infoBO.queryByInfoStrategy(infoStrategyList);
            List<Integer> ids = new ArrayList<>(infoList.size());
            CollectionUtils.collect(infoList, infoIdentityTransformer, ids);
            reportDataQuery.setIdentityIds(ids);
        }
        if (CollectionUtils.isNotEmpty(rs.getNums())) {
            reportDataQuery.setNums(rs.getNums());
        }
        if (CollectionUtils.isNotEmpty(rs.getRuleIds())){
            reportDataQuery.setRuleIds(rs.getRuleIds());
        }
        List<ReportData> reportDataList = reportDataBO.findByQuery(reportDataQuery).getData();
        //转换总数
//        rs.setCount(reportDataQuery.getCount());
        List<ReportDataSearchVO> reportDataSearchVOList = new ArrayList<>(reportDataList.size());
        for (ReportData reportData : reportDataList) {
            reportDataSearchVOList.add(new ReportDataSearchVO(reportRuleBO.get(reportData.getReportRuleId()),reportData,identityBO.getUserDesc(reportData.getIdentityId())));
        }
        return reportDataSearchVOList;
    }

    @Override
    public ReportCount countByUser(Integer id) {
        if (id == null){
            return null;
        }
        int count = reportRuleBO.countByQuery(new Query());
        SimpleReportDataQuery simpleReportDataQuery = new SimpleReportDataQuery();
        simpleReportDataQuery.setIdentityIds(Collections.singletonList(id));
        int reportAllCount = reportDataBO.countByQuery(simpleReportDataQuery);
        simpleReportDataQuery.setSupplement(1);
        int reportTwoCount = reportDataBO.countByQuery(simpleReportDataQuery);

        ReportCount reportCount = new ReportCount();
        reportCount.setSubCount(reportAllCount);
        reportCount.setTwoCount(reportTwoCount);
        reportCount.setErrCount(count - reportAllCount);

        return reportCount;
    }
}
